package au.org.htd.youslide;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Tag extends DbObject {
   @SuppressWarnings("unused")
   private static final Logger log = Logger.getLogger(Tag.class.getName());

   @Persistent
   private String name;

   @Persistent
   private List<Long> songs;

   public Tag(PersistenceManager pm, String name) {
      super(pm);
      this.name = name;
      songs = new ArrayList<Long>();
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public boolean addSong(Long id) {
      if (songs.contains(id)) {
         return false;
      } else {
         return songs.add(id);
      }
   }

   public void removeSong(Long id) {
      if (null != songs) {
         songs.remove(id);
      }
   }

   public int songCount() {
      if (null != songs) {
         return songs.size();
      } else {
         return 0;
      }
   }

   @SuppressWarnings("unchecked")
   public static Tag getTagByName(PersistenceManager pm, String name) {
      String query = "select from " + Tag.class.getName() + " where name == '"
            + name + "'";
      List<Tag> results = (List<Tag>) pm.newQuery(query).execute();
      Tag tag;
      if (results.size() > 0) {
         tag = results.get(0);
         tag.setPm(pm);
      } else {
         tag = null;
      }
      return tag;
   }

   public JSONArray getSongs() {
      JSONArray ids = new JSONArray();
      if (null != songs) {
         for (Long id : songs) {
            ids.put(id);
         }
      }
      return ids;
   }

   public List<Long> getSongIds() {
      if (null != songs) {
         return songs;
      } else {
         return new ArrayList<Long>();
      }
   }

   public static JSONArray getSongsByTags(String tags) {
      StringTokenizer tok = new StringTokenizer(tags, ",");
      List<List<Long>> songLists = new ArrayList<List<Long>>();
      while (tok.hasMoreTokens()) {
         Tag tag = getTagByName(PMF.getPM(), tok.nextToken());
         songLists.add(tag.getSongIds());
         tag.closeConnection();
      }
      List<Long> first = songLists.get(0); // there should always be at least 1
      for (int i = 1; i < songLists.size() && first.size() > 0; i++) {
         first.retainAll(songLists.get(i));
      }
      SongProject song = new SongProject(PMF.getPM());
      JSONArray songs = new JSONArray();
      for (Long id : first) {
         songs.put(song.get(id).toJSON());
      }
      song.closeConnection();
      return songs;
   }

   @SuppressWarnings("unchecked")
   public static JSONArray getTagsArray() throws JSONException {
      PersistenceManager pm = PMF.getPM();
      String query = "select from " + Tag.class.getName();
      JSONArray tags = new JSONArray();
      for (Tag tag : (List<Tag>) pm.newQuery(query).execute()) {
         JSONObject jtag = new JSONObject();
         jtag.put("name", tag.getName());
         jtag.put("count", tag.songCount());
         tags.put(jtag);
      }
      pm.close();
      return tags;
   }

   @Override
   public Tag get(Long id) {
      Tag tag = pm.getObjectById(Tag.class, id);
      tag.setPm(pm);
      return tag;
   }
}